package org.devocean.groupbuying.web.backend;

import java.security.Principal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.devocean.groupbuying.domain.Article;
import org.devocean.groupbuying.domain.CategoriesLocalization;
import org.devocean.groupbuying.domain.Media;
import org.devocean.groupbuying.domain.Merchant;
import org.devocean.groupbuying.domain.Tags;
import org.devocean.groupbuying.service.MerchantService;
import org.devocean.groupbuying.service.UserService;
import org.devocean.groupbuying.utils.RenderMapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
@RequestMapping(value="/gb-cpanel/merchants")
public class MerchantsController {
	
	
	@Autowired
	private MerchantService merchantService;
	
	@Autowired
	private UserService userService;
	
	@RequestMapping(value="/",method=RequestMethod.GET)
	public Map<String, ? extends Object> getAllMerchants(
			@RequestParam(value = "query",defaultValue="") String query,
			@RequestParam(value = "start", required = false) Integer start,
			@RequestParam(value = "limit", required = false) Integer size){
		
		try {
			
		
		List<Merchant> merchants = merchantService.getMerchantsByCriteria(query,start, size);
		
		List<Map<String, Object>> result = new ArrayList<Map<String,Object>>();
		for (Merchant merchant : merchants) {
			Map<String, Object> data = new ConcurrentHashMap<String, Object>();
			Article article=null;
			try{
			 Iterator<Article> it = merchant.getArticlesLocalization().getArticles().iterator();
			 if(it.hasNext())
			 article = it.next();
			}
			catch (Exception e) {
				e.printStackTrace();
			}
			
			if(article!=null){
				data.put("merchantID", merchant.getMerchantID());
				data.put("title", article.getTitle());
				data.put("lang", article.getLang());
				data.put("description", article.getBody());
				data.put("url", merchant.getUrl());
				if(merchant.getAdress()=="")
					data.put("adress", "_");
				else
					data.put("adress", merchant.getAdress());
				data.put("country", merchant.getCountry());
				if(merchant.getEmail()==""){
					data.put("email", "_");
				}
				else
					data.put("email", merchant.getEmail());
				data.put("country", merchant.getCountry());
				
				data.put("alexa", merchant.getAlexa());
			}
			result.add(data);
		}
		
		long total = merchantService.countMerchantsBycriteria(query);
		return RenderMapUtils.getMap(result, total);
		}catch (Exception e) {
			return RenderMapUtils
					.getModelMapError("Error retrieving Merchants from database.");
		}
	}
	@RequestMapping(value="/",method=RequestMethod.POST)
	public @ResponseBody Map<String, ? extends Object>  addOrUpdate(@RequestBody Merchant merchant,Principal principal){
		
		
		try{
			merchant.getArticlesLocalization().getArticles().iterator().next()
			.setOwner(userService.getUserById(Integer.valueOf(principal.getName())));
			Merchant newMerchant = merchantService.addOrUpdateMerchant(merchant);
			
			Map<String, Object> data = new ConcurrentHashMap<String, Object>();
			Article article = newMerchant.getArticlesLocalization().getArticles().iterator().next();
			data.put("articleID", article.getArticleID());
			data.put("title", article.getTitle());
			data.put("lang", article.getLang());
			data.put("articlesLocalizationID", newMerchant.getArticlesLocalization().getArticlesLocalizationID());
			data.put("merchantID", newMerchant.getMerchantID());
			return RenderMapUtils.getMap(data);
		}catch (Exception e) {
			e.printStackTrace();
			return RenderMapUtils
					.getModelMapError("Error retrieving Merchant from database.");
		}
		
	}
	@RequestMapping(value="/{merchantID}",method=RequestMethod.GET)
	public Map<String, ? extends Object> getMerchant(@PathVariable("merchantID") Integer merchantID){
		
		try{
		Merchant merchant = merchantService.getMerchantById(merchantID);
				
		return RenderMapUtils.getMap(this.renderMerchant(merchant));
		}catch (Exception e) {
			return RenderMapUtils
					.getModelMapError("Error retrieving Merchant from database.");
		}
	}
	@RequestMapping(value="/{merchantID}",method=RequestMethod.DELETE)
	public void deleteMerchant(@PathVariable("merchantID") Integer merchantID){
		merchantService.removeMerchant(merchantID);
	}
	
	public Map<String, Object> renderMerchant(Merchant merchant){
		
		Integer[] cl_ids = new Integer[merchant.getArticlesLocalization().getCategoriesLocalizations().size()];
		Integer[] tags_ids = new Integer[merchant.getArticlesLocalization().getTags().size()];
		Map<String, Object> data = new ConcurrentHashMap<String, Object>();
		Article article = merchant.getArticlesLocalization().getArticles().iterator().next();
		data.put("merchantID", merchant.getMerchantID());
		data.put("title", article.getTitle());
		data.put("body", article.getBody());
		data.put("shorte", article.getShorte());
		data.put("lang",article.getLang());
		data.put("articleID", article.getArticleID());
		data.put("url", merchant.getUrl());
		data.put("phone", merchant.getPhone());
		
		if(merchant.getAdress()=="")
			data.put("adress", "_");
		else
			data.put("adress", merchant.getAdress());
		data.put("country", merchant.getCountry());
		if(merchant.getEmail()==""){
			data.put("email", "_");
		}
		else
			data.put("email", merchant.getEmail());
		data.put("alexa", merchant.getAlexa());
		data.put("articlesLocalizationID", merchant.getArticlesLocalization().getArticlesLocalizationID());
		
		int i = 0;
		Iterator<CategoriesLocalization> iteratorCategories = merchant.getArticlesLocalization().getCategoriesLocalizations().iterator();
		while (iteratorCategories.hasNext()) {
			cl_ids[i++] = iteratorCategories.next().getCategoriesLocalizationID();
			
		}
		
		int j = 0;
		Iterator<Tags> tagIterator = merchant.getArticlesLocalization().getTags().iterator();
		
		while (tagIterator.hasNext()) {
			Tags tag = tagIterator.next();
			tags_ids[j++] = tag.getTagsID();
		}		
		List<Map<String, Object>> mediaList = new ArrayList<Map<String, Object>>();
		
				for (Media m :	merchant.getArticlesLocalization().getMediaLocalizations()) {
					Map<String, Object> dataMedia = new ConcurrentHashMap<String, Object>();
					dataMedia.put("mediaID", m.getMediaID());
					dataMedia.put("title", m.getTitle());
					dataMedia.put("media_file_path", m.getMediaFilePath());
					mediaList.add(dataMedia);
		
				}
		data.put("articlesMedia", mediaList);
		data.put("_categoriesProxy", cl_ids);
		data.put("_tagsProxy", tags_ids);
		return data;
	}
	
	@RequestMapping(value = "/search", method = RequestMethod.GET)
	public Map<String,Object> search(String searchText,
									@RequestParam(value = "start", required = false) Integer start,
									  @RequestParam(value = "limit", required = false) Integer limit) {
		try {
			 
			return merchantService.search(searchText, new ConcurrentHashMap<String, Object>(3));
			 			
		} catch (Exception e) {
			e.printStackTrace();
			return RenderMapUtils.getModelMapError("No data found!");

		}
	
	}
}
